package com.dhj.jvmstudy.chapter02;


/**
 * 类加载器
 */
public class ClassLoaderTest {

    public static void main(String[] args) {

        // 获取系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader); // sun.misc.Launcher$AppClassLoader@18b4aac2

        // 获取其上层的扩展类加载器
        ClassLoader extClassLoader = systemClassLoader.getParent();
        System.out.println(extClassLoader); // sun.misc.Launcher$ExtClassLoader@53d8d10a

        // 试图获取其上层，实际上获取不到引导类加载器
        ClassLoader bootstrapClassLoader = extClassLoader.getParent();
        System.out.println(bootstrapClassLoader); // null


        // 对于用户自定义的类来说，获取其类加载器
        ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
        System.out.println(classLoader); // sun.misc.Launcher$AppClassLoader@18b4aac2

        // 试图获取String类的类加载器，证明String类是使用引导类加载器进行加载的。
        // Java的核心类库都是使用引导类加载器进行加载的。
        ClassLoader classLoader1 = String.class.getClassLoader();
        System.out.println(classLoader1); // null

        /**
         * 由于BootstrapClassLoader是由C/C++编写的，再加上其只加载Java核心类库的类，
         * 所以无法通过一个普通类来获取其对象。
         */

        /**
         * JVM必须知道一个类型是由启动类加载器加载的还是由用户类加载器加载的。
         * 如果一个类是由用户类加载器加载的，那么JVM会将这个类加载器的一个引用作为类型信息的一部分保存在方法区中。
         * 如果一个类是由启动类加载器加载的，那么JVM则不会保存该类加载器的引用，因此也就无法通过getClassLoader方法拿到引用信息，也就出现了null。
         */

    }

}
